﻿// -----------------------------------------------------------------------
// <copyright file="Shot.cs" company="Microsoft">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace SpaceshipDuel
{
    using Microsoft.Xna.Framework;
    using Microsoft.Xna.Framework.Graphics;
    using System;

    /// <summary>
    /// Klasse für Geschosse
    /// </summary>
    public class Bullet : GameObject
    {
        #region Private fields

        bool destroyMe;             // Flag zum Löschen
        int damage;                 // Schaden, der durch das Geschoss verursacht wird
        float speed;                // Geschwindigkeit
        float rotationAngle;        // Rotationswinkel
        float maxTravelDistance;    // Maximale Strecke, die das Geschoss zurücklegen kann, bevor er gelöscht wird
        Vector2 direction;          // Richtungsvektor der Schussrichtung (normiert)
        Vector2 startPosition;      // Startpunkt
        Vector2 originVector;       // Rotationsvektor der Textur

        #endregion Private fields

        #region Public properties

        public bool DestroyMe
        {
            get { return this.destroyMe; }
            set { this.destroyMe = value; }
        }

        public float RotationAngle
        {
            get { return this.rotationAngle; }
            set { this.rotationAngle = value; }
        }

        public int Damage
        {
            get { return this.damage; }
            set { this.damage = value; }
        }

        #endregion Public properties

        #region Construction

        /// <summary>
        /// Konstruktor
        /// </summary>
        /// <param name="newTexture">Textur des Schusses</param>
        /// <param name="newPosition">Startposition des Schusses</param>
        /// <param name="newWorldSize">Größe des Spielfeldes</param>
        /// <param name="newSpeed">Geschossgeschwindigkeit</param>
        /// <param name="newRotation">aktueller Rotationswinkel des Raumschiffs = Orientierung der Schusstextur</param>
        /// <param name="newDirection">Richtungsvektor für Richtung des Schusses (normiert)</param>
        /// <param name="newMaxTravelDistance">Reichweite des Schusses</param>
        public Bullet(TextureData newTextureData, Vector2 newCenter, int newWorldSize, float newSpeed, float newRotation, Vector2 newDirection, float newMaxTravelDistance, int newDamage = 1)
        {
            textureData = newTextureData;
            originVector = new Vector2(textureData.halfwidth, textureData.halfheight);
            center = newCenter;
            startPosition = newCenter;
            speed = newSpeed;
            worldSize = newWorldSize;
            direction = newDirection;
            rotationAngle = newRotation;
            maxTravelDistance = newMaxTravelDistance;
            destroyMe = false;
            damage = newDamage;

            Update();
        }

        #endregion Construction

        #region Public methods

        /// <summary>
        /// Update-Methode für den Schuss
        /// </summary>
        new public void Update()
        {
            if (destroyMe == false)
            {
                center += direction * speed;
                    
                CheckPosition();

                float distance = (startPosition - center).Length();

                if (distance >= maxTravelDistance)
                    destroyMe = true;
            }
        }

        /// <summary>
        /// Draw-Methode für den Schuss
        /// </summary>
        /// <param name="spriteBatch">Spritebacth</param>
        /// <param name="xOffset">Offset X</param>
        /// <param name="yOffset">Offset Y</param>
        new public void Draw(SpriteBatch spriteBatch, float xOffset = 0f, float yOffset = 0f)
        {
            if (destroyMe == false)
            {
                Vector2 positionVector = new Vector2(center.X + xOffset, center.Y + yOffset);
                spriteBatch.Draw(textureData.texture, positionVector, null, Color.White, rotationAngle, originVector, 1.0f, SpriteEffects.None, 0f);
            }
        }

        #endregion Public methods

        #region Private methods

        /// <summary>
        /// Korrektur der Position, wenn der Schuss über den Spielfeldrand hinausfliegt
        /// </summary>
        private void CheckPosition()
        {
            if (center.X < 0)
            {
                float distance = (startPosition - center).Length();
                center.X = worldSize + center.X;
                RecalculateMaxTravelDistance(distance);
            }
            else if (center.X >= worldSize)
            {
                float distance = (startPosition - center).Length();
                center.X = center.X - worldSize;
                RecalculateMaxTravelDistance(distance);
            }

            if (center.Y < 0)
            {
                float distance = (startPosition - center).Length();
                center.Y = worldSize + center.Y;
                RecalculateMaxTravelDistance(distance);
            }
            else if (center.Y >= worldSize)
            {
                float distance = (startPosition - center).Length();
                center.Y = center.Y - worldSize;
                RecalculateMaxTravelDistance(distance);
            }
        }

        /// <summary>
        /// Anpassung der MaxDistanz-Berechnung, wenn der Schuss über den Spielfeldrand hinausfliegt
        /// </summary>
        /// <param name="distance">bisher zurückgelegte Entfernung des Schusses</param>
        private void RecalculateMaxTravelDistance(float distance)
        {
            maxTravelDistance -= distance;
            startPosition = center;
        }

        #endregion Private methods
    }
}
